/**
 * =====================================================================================
 *       @file  ngx_request.c
 *      @brief  
 *
 *  Detailed description starts here.
 *
 *   @internal
 *     Created  2012年05月15日 14时47分24秒 
 *    Revision  1.0.0.0
 *    Compiler  gcc/g++
 *
 *     @author  luis
 * =====================================================================================
 */

#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include "ngx_connection.h"
#include "ngx_core.h"
#include "ngx_request.h"
#include "ngx_event.h"

static void echo(int fd, u_char *buf, size_t len)
{
    size_t n;

    while (1)
    {
        n = send(fd, buf, len, 0);
        if (n <= 0)
        {
            if (errno == EINTR || errno == EAGAIN)
            {
                continue; 
            }
            else
            {
                return;
            }
        }
        len -= n;
        if (len == 0)
        {
            return; 
        }
    }
}

static void ngx_read_data(ngx_event_t *rev)
{
    size_t                       i, n, len;
    ngx_connection_t            *c;
    char                         buf[4 * 1024];

    c = rev->data;
    
    len = 0;
    while (1)
    {
        n = c->recv(c, buf + len, sizeof(buf) - len);
        if (n == 0)
        {
            printf("connection:%d closed", c->fd); 
        }
        else if (n == NGX_AGAIN || n == NGX_ERROR)
        {
            return; 
        }

        if (buf[len + n - 1] == '\n')
        {
            len += n;
            echo(c->fd, buf, len);
            return;
        }
        else
        {
            len += n;
        }
    }
}

void ngx_init_connection(ngx_connection_t *c)
{
    ngx_event_t *rev;         

    rev = c->read;
    rev->handler = ngx_read_data;

    ngx_add_event(rev, NGX_READ_EVENT, NGX_CLEAR_EVENT);
}
